#I Import and Initialize
import sys, pygame, game
from scenes import *
from data import *
pygame.init()



#############################################################################
# Represents a menu screen.
#############################################################################
class Menu(object):
    


    #############################################################################
    # Initializes a new instance of Menu.
    #############################################################################
    def __init__(self, screen):
        #A Assign
        self.screen = screen
        self.keepGoing = True
        self.root = True
        self.menu = None
        self.selectedLevel = -1
        self.text = "Gebruik de pijltjestoetsen om het menu door te lopen en druk op Enter."

        # Action
        self.root_menu()
        self.main_loop()
    


    #############################################################################
    # Starts a new game.
    #############################################################################   
    def new_game(self):
        game.Game(self.screen) 
    


    #############################################################################
    # Gets the highest level the player has completed.
    #############################################################################    
    def get_saved_lvl(self):
        i = game.count_levels()
        while i > 0:
            if os.path.exists(filepath("..\saves\lvl%d.sav" % i)):
                return i
            i -= 1
        return 0
    


    #############################################################################
    # Gets the score of a specific level if available. 0 otherwise.
    #############################################################################
    def get_lvl_score(self, lvl):
        try:
            return int(open(filepath("..\saves\lvl%d.sav" % lvl)).read())
        except:
            return 0
    


    #############################################################################
    # Build the 'Level select' submenu.
    #############################################################################    
    def levels(self):
        i = 1
        optList = []
        while i <= game.count_levels():
            levelStr = "Level %d" % i
            scoreStr = "(Highscore %d)" % self.get_lvl_score(i)
            text = "%(level)s %(score)s" % {'level':levelStr, 'score':scoreStr}
            optList.append([text, lambda: self.play_level()])
            i += 1
        optList.append(["Back", lambda: self.root_menu()])
        
        options = tuple(optList)
        
        self.menu = MenuStyle(self, self.text, options)
        self.set_menu(self.menu, False, 32)
    


    #############################################################################
    # Builds the root menu.
    #############################################################################   
    def root_menu(self):
        self.menu = MenuStyle(self, self.text, (
            ["New Game", lambda: self.new_game()],
            ["Help", lambda: self.help(self.screen)],
            ["Select Level", lambda: self.levels()],
            ["Quit Game", lambda: self.quit()]))
        self.set_menu(self.menu, True, 64)
    


    #############################################################################
    # Sets the menu.
    #############################################################################    
    def set_menu(self, menu, bool, fsize):
        self.root = bool
        menu.set_font(pygame.font.Font(filepath("fonts/font2.ttf"), fsize))
        menu.set_highlight_color((0, 255, 0))
        menu.set_normal_color((255, 255, 255))
    


    #############################################################################
    # Plays the currently selected level.
    #############################################################################    
    def play_level(self):
        unlocklvl = self.get_saved_lvl() + 1
        if self.selectedLevel <= unlocklvl:
            game.Game(self.screen, self.selectedLevel)
        else:
            self.menu.set_highlight_color((255, 0, 0))
     


    #############################################################################
    # Displays the 'Help' screen.
    #############################################################################   
    def help(self, screen):
        scene(screen, ["HELP",
        "",
        "Move: Arrow Keys",
        "Shoot: Spacebar",
        "Back to Menu: Esc",
        "Note: Don't get hit!",
        ""])
    


    #############################################################################
    # Quits the application.
    #############################################################################
    def quit(self):
        sys.exit()
    


    #############################################################################
    # Continously updates this menu.
    #############################################################################    
    def main_loop(self):
        #L Loop
        while self.keepGoing:
            
            #E Event
            self.events = pygame.event.get()
    
            self.menu.update(self.events)
            
            for e in self.events:
                if e.type == pygame.QUIT:
                    quit()   
                elif e.type == pygame.KEYDOWN:
                    if e.key == pygame.K_ESCAPE:
                        if self.root:
                            self.keepGoing = False
                        else:
                            self.root_menu()
            #R Refresh
            self.screen.fill((0, 0, 0))
            self.menu.draw(self.screen)
            pygame.display.flip()



#############################################################################
# Represents an interface for styling a menu.
#############################################################################            
class MenuStyle:
    


    #############################################################################
    # Initializes a new instance of MenuStyle.
    #############################################################################
    def __init__(self, parent, text, *options):
        #E Entities
        self.enterSound = load_sound("enter.ogg")
        self.selectSound = load_sound("select.ogg")
        self.confirmSound = load_sound("confirm.ogg")
        
        #A Assign
        self.options = options
        self.parent = parent
        self.text = text
        self.x = 0
        self.y = 0
        self.font = pygame.font.Font(None, 32)
        self.option = 0
        self.width = 1
        self.color = [0, 0, 0]
        self.hcolor = [255, 0, 0]
        self.height = len(self.options)*self.font.get_height()        
        
        #A Action
        self.enterSound.play()
        
        for i in range(0, len(self.options[0])):
            str = self.options[0][i][0]
            ren = self.font.render(str, 1, (0, 0, 0))
            if ren.get_width() > self.width:
                self.width = ren.get_width()
    


    #############################################################################
    # Draws this menu.
    #############################################################################
    def draw(self, surface):
        for i in range(0, len(self.options[0])):
            if i == self.option:
                clr = self.hcolor
            else:
                clr = self.color
            str = self.options[0][i][0]
            ren = self.font.render(str, 1, clr)
            if ren.get_width() > self.width:
                self.width = ren.get_width()
            height = len(self.options[0]) * self.font.get_height()
            surface.blit(ren, (game.SCREEN_WIDTH / 2 - ren.get_width()/2, (game.SCREEN_HEIGHT/4 + i*self.font.get_height())))
            
            tempFont = pygame.font.Font(filepath("fonts/font2.ttf"), 16)
            ren = tempFont.render(self.text, 1, (255,255,255))
            surface.blit(ren, (game.SCREEN_WIDTH / 2 - ren.get_width()/2, game.SCREEN_HEIGHT - tempFont.get_height()))
            
    


    #############################################################################
    # Handles menu key events.
    #############################################################################        
    def update(self, events):
        for e in events:
            if e.type == pygame.KEYDOWN:
                if e.key == pygame.K_DOWN:
                    self.selectSound.play()
                    self.option += 1
                if e.key == pygame.K_UP:
                    self.selectSound.play()
                    self.option -= 1
                if e.key == pygame.K_RETURN:
                    self.confirmSound.play()
                    self.parent.selectedLevel = self.option + 1
                    self.options[0][self.option][1]()
        if self.option > len(self.options[0])-1:
            self.option = 0
        if self.option < 0:
            self.option = len(self.options[0])-1
    


    #############################################################################
    # Sets the position of text within this menu.
    #############################################################################
    def set_pos(self, x, y):
        self.x = x
        self.y = y
    


    #############################################################################
    # Sets the font that will be used to display this menu.
    #############################################################################    
    def set_font(self, font):
        self.font = font
    


    #############################################################################
    # Sets the color in which highlighted items will appear.
    #############################################################################    
    def set_highlight_color(self, color):
        self.hcolor = color
    


    #############################################################################
    # Sets the color in which menuitems will normally be shown.
    #############################################################################    
    def set_normal_color(self, color):
        self.color = color
    


    #############################################################################
    # Sets itself.
    #############################################################################
    def set_menu(self, menu, bool, fsize):
        self.root = bool
        menu.set_font(pygame.font.Font(filepath("fonts/font2.ttf"), fsize))
        menu.set_highlight_color((0, 255, 0))
        menu.set_normal_color((255, 255, 255))